typedef struct {
      int front;
      int rear;
      int *data;
      int size;
} MyCircularQueue;

bool myCircularQueueIsEmpty(MyCircularQueue* obj);  
bool myCircularQueueIsFull(MyCircularQueue* obj);

MyCircularQueue* myCircularQueueCreate(int k) {
      MyCircularQueue *q=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
      q->data=(int *)malloc(sizeof(int)*(k+1));
      q->front=0;
      q->rear=0;
      q->size=k+1;
      return q;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
      if(myCircularQueueIsFull(obj)){
        return false;
      }
      obj->data[obj->rear]=value;
      obj->rear=(obj->rear+1)%(obj->size);
      return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj)){
      return false;
    }
    obj->front=(obj->front+1)%(obj->size);
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
     if(myCircularQueueIsEmpty(obj)){
       return -1;
     }
     return obj->data[obj->front];
}

int myCircularQueueRear(MyCircularQueue* obj) {
      if(myCircularQueueIsEmpty(obj)){
        return -1;
      }
      return obj->data[(obj->rear-1+obj->size)%(obj->size)];  
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
     if(obj->front==obj->rear){
       return true;
     }
     return false;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
      if((obj->rear+1)%obj->size==obj->front){
        return true;
      }
      return false;
}

void myCircularQueueFree(MyCircularQueue* obj) {
        free(obj->data);
        free(obj);
}
